//go:build hashpwd
// +build hashpwd

package main

import (
	"bytes"
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/virzz/logger"
	"github.com/virzz/virzz/modules/crypto/hashpwd"
)

type Pos struct {
	Comment         string
	Start, End, Len int
}

func GenerateLookup() error {
	_pos := make(map[hashpwd.EncMethed]Pos, len(hashpwd.MethedLen))
	var t int
	for i := 0; i < len(hashpwd.MethedLen); i++ {
		_i := hashpwd.EncMethed(i)
		_pos[_i] = Pos{Start: t, End: t + hashpwd.MethedLen[_i], Len: hashpwd.MethedLen[_i], Comment: _i.String()}
		t += hashpwd.MethedLen[_i]
	}
	setLen := map[int]struct{}{}
	setLenArr := []int{}
	for _, pos := range _pos {
		setLen[pos.Len] = struct{}{}
	}
	for k := range setLen {
		setLenArr = append(setLenArr, k)
	}
	sort.Ints(setLenArr)

	var buff bytes.Buffer
	buff.WriteString("// Code generated by \"script/generate_lookup.go\"; DO NOT EDIT.\npackage hashpwd\nfunc LookUp(line, pwd string) bool {\nswitch len(pwd) {\n")
	for _, i := range setLenArr {
		buff.WriteString(fmt.Sprintf("case %d:\n", i))
		var con = []string{}
		for j := 0; j < len(hashpwd.MethedLen); j++ {
			pos := _pos[hashpwd.EncMethed(j)]
			if pos.Len == i {
				con = append(con, fmt.Sprintf("pwd == /* %s */ line[%d:%d] ", pos.Comment, pos.Start, pos.End))
			}
		}
		buff.WriteString(fmt.Sprintf("return %s\n", strings.Join(con, " || \r\n ")))
	}
	buff.WriteString("}\nreturn false\n}")
	f, err := os.OpenFile("hashpwd_lookup.go", os.O_CREATE|os.O_RDWR, os.ModePerm)
	if err != nil {
		return err
	}
	defer f.Close()
	f.Truncate(0)
	_, err = buff.WriteTo(f)
	return err
}

func main() {
	err := GenerateLookup()
	if err != nil {
		logger.Error(err)
		return
	}
	logger.Success("Generated")
}
